package cn.school.workflow.service.impl;

import cn.school.common.utils.SysUserUtils;
import cn.school.sys.dao.SysDeptDao;
import cn.school.sys.dao.SysUserDao;
import cn.school.sys.entity.SysUser;
import cn.school.workflow.dao.StudentLeaveApplyDao;
import cn.school.workflow.dao.StudentLeaveSelfApplyDao;
import cn.school.workflow.dao.TenantFlowDao;
import cn.school.workflow.dao.WorkFlowCommonDao;
import cn.school.workflow.entity.ActReProcdef;
import cn.school.workflow.entity.TenantFlow;
import cn.school.workflow.service.WorkFlowCommonService;
import cn.school.workflow.vo.StudentLeaveApplyVO;
import cn.school.workflow.vo.StudentLeaveSelfApplyVO;
import cn.school.workflow.vo.WorkFlowHiVO;
import cn.school.workflow.vo.WorkFlowVO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.activiti.engine.*;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class WorkFlowCommonServiceImpl  implements WorkFlowCommonService {

    @Autowired
    private WorkFlowCommonDao workFlowCommonDao;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private SysUserDao sysUserDao;

    @Autowired
    private SysDeptDao sysDeptDao;

    @Resource
    private ProcessEngine processEngine;

    @Autowired
    private RepositoryService repositoryService;

    @Override
    public IPage<ActReProcdef> findProcessDeployList(ActReProcdef vo) {
        String tenantId = SysUserUtils.getSysUser().getTenantId();
        vo.setTenantId(tenantId);
        int startNum=(vo.getPageNum()-1)*vo.getPageSize();
        int count = 0;
        List<ActReProcdef> enrollList =  workFlowCommonDao.findProcessDeployList(vo,  vo.getPageSize(),startNum);
        if(enrollList.size() <=0 || enrollList == null){
            count = 0;
        }else {
            count =  workFlowCommonDao.findProcessDeployListCount(vo);
        }
        IPage<ActReProcdef> page = new Page<>();
        page.setTotal(count);
        page.setRecords(enrollList);
        return page;
    }

    @Override
    public String createProcessInstance(WorkFlowVO vo) {
        log.info("createProcessInstance：{}", JSON.toJSONString(vo));
        ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder().processDefinitionKey(vo.getApplyID())
                .name(vo.getApplyTitle())
                .businessKey(vo.getBusinessKey())
                .variables(vo.getVariables())
                .start();
        String processInstanceId = processInstance.getProcessInstanceId();
        log.info("create success ProcessInstanceId ：{}", processInstanceId);
        //流程创建后返回流程实例的ID，该ID会保存到申请单表中
        return processInstanceId;
    }

    @Override
    public Boolean cancelApply(String processInstanceId,String reason) {
        ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
                .singleResult();
        if(instance==null){
            log.info("cancelApply process Instance is null");
            //修改已经结束，不能撤销
            return false;
        }
        runtimeService.deleteProcessInstance(processInstanceId,reason);
        log.info("cancelApply delete process success");
        //正常执行，则撤销成功
        return true;
    }

    @Override
    public List<WorkFlowHiVO> historyWorkFlowList(String processInstance) {

        List<HistoricTaskInstance> list=historyService // 历史相关Service
                .createHistoricTaskInstanceQuery() // 创建历史任务实例查询
                .processInstanceId(processInstance) // 用流程实例id查询
//                .finished() // 查询已经完成的任务
//                .listPage(startNum,pageSize);
                .list();
        //给list排序
        list.stream().sorted(Comparator.comparing(HistoricTaskInstance::getStartTime));
        List<WorkFlowHiVO> hiList = new ArrayList<>();
        list.stream().forEach(
                ht -> {
                    WorkFlowHiVO hiVO = new WorkFlowHiVO();
                    hiVO.setTaskName(ht.getName());
                    List<Comment> taskComments = taskService.getTaskComments(ht.getId());
                    String msg = "";
                    for(Comment c : taskComments){
                        msg += c.getFullMessage();
                    }
                    hiVO.setDescription(msg);
                    hiVO.setAssignee(ht.getAssignee());
                    hiVO.setStartTime(ht.getStartTime());
                    if(ht.getEndTime() != null){
                        hiVO.setEndTime(ht.getEndTime());
                    }
                    hiVO.setDeleteReason(ht.getDeleteReason());
                    hiList.add(hiVO);
                }
        );
//        List<HistoricActivityInstance> list1 =historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstance)
//                .orderByHistoricActivityInstanceStartTime().desc().list();
//
////输出查询结果
//        for(HistoricActivityInstance hi:list1){
//            System.out.println(hi.getActivityId());
//            System.out.println(hi.getActivityName());
//            System.out.println(hi.getActivityType());
//            System.out.println(hi.getAssignee());
//            System.out.println(hi.getProcessDefinitionId());
//            System.out.println(hi.getProcessInstanceId());
//            System.out.println("------------------------");
//        }
//        WorkFlowHiVO vo = new WorkFlowHiVO();
//        vo.setProcessInstanceId(processInstance);
//        List<WorkFlowHiVO> hiList  = workFlowCommonDao.historyWorkFlowList(vo);
        return hiList;
    }

    @Override
    public WorkFlowVO processWorkFlow(WorkFlowVO vo) {
        String processInstanceId = vo.getProcessInstanceId();
        SysUser user = SysUserUtils.getSysUser();
        log.info("workFlowVO String {}" ,JSON.toJSONString(vo));
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
                .singleResult();
        Map<String,Object> args = vo.getVariables();

        if(0 == vo.getFlag()){
            args.put("flag", vo.getFlag());
        }else {
            args.put("flag", vo.getFlag());
            args.put("tenantId", Integer.valueOf(vo.getTenantId()));
        }
//        if(vo.getVariables()!=null){
//            args.put("assignee0", "test2");//下级审批人
//        }
        String applyDesc = vo.getFlag()==0?"【不同意】":"【同意】";

        taskService.claim(vo.getTaskId(),user.getUsername());
        Authentication.setAuthenticatedUserId(user.getUsername());
        taskService.addComment(vo.getTaskId(),vo.getProcessInstanceId(),applyDesc+vo.getApplyDesc());

//        args = processCountersign(vo.getProcessInstanceId(),vo.getTaskId(),args,vo.getFlag());
        //查询会签人数
        taskService.complete(vo.getTaskId(),args);

        return vo;
    }



    @Override
    public WorkFlowVO workFlowInfo(String processInstanceId) {
        String username = SysUserUtils.getSysUser().getUsername();
//        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
//                .singleResult();

        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).taskCandidateOrAssigned(username).singleResult();
        if(task==null){
            return new WorkFlowVO();
        }
        String excId =task.getExecutionId();
                //获取流程的当前节点信息
        ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery().executionId(excId).singleResult();

        WorkFlowVO vo = null;
        if(task!=null){
            vo = new WorkFlowVO();
//            vo.setApplyID(pi.getProcessDefinitionKey());
//            vo.setProcessInstanceId(pi.getProcessInstanceId());
//            vo.setBusinessKey(pi.getBusinessKey());
//            vo.setApplyTitle(pi.getName());
            vo.setApplyID(task.getProcessDefinitionId());
            vo.setProcessInstanceId(task.getProcessInstanceId());
            vo.setBusinessKey(task.getBusinessKey());
            vo.setApplyTitle(task.getName());
            vo.setCurrNode(execution.getActivityId());
            vo.setTaskId(task.getId());
        }
        return vo;
    }

    @Resource
    private StudentLeaveApplyDao studentLeaveApplyDao;

    @Resource
    private StudentLeaveSelfApplyDao studentLeaveSelfApplyDao;

    @Override
    public IPage<WorkFlowVO> findCurrUserToDoTasks(WorkFlowVO vo) {
        String username = SysUserUtils.getSysUser().getUsername();
        int startNum=(vo.getPageNum()-1)*vo.getPageSize();
        List<Task> taskList  = taskService.createTaskQuery().processDefinitionKeyLike(vo.getApplyID()).taskInvolvedUser(username)
//                .taskCandidateUser(username)
                .orderByTaskCreateTime()
                .desc()
                .listPage(startNum,vo.getPageSize());
        Long count = taskService.createTaskQuery().processDefinitionKeyLike(vo.getApplyID())
                .taskInvolvedUser(username).count();
        List<WorkFlowVO> leaveTasks = new ArrayList<>();
        for (Task task : taskList) {
            WorkFlowVO flowVO = new WorkFlowVO();
            flowVO.setTaskId(task.getId());
            flowVO.setName(task.getName());
            flowVO.setProcessInstanceId(task.getProcessInstanceId());
            flowVO.setProcessDefinitionId(task.getProcessDefinitionId());
            flowVO.setCreateTime(task.getCreateTime());
//            Map<String, Object> leaveTask = new HashMap<>();
//            leaveTask.put("taskId",task.getId());
//            leaveTask.put("name",task.getName());
//            leaveTask.put("processDefinitionId",task.getProcessDefinitionId());
//            leaveTask.put("processInstanceId",task.getProcessInstanceId());
//            leaveTask.put("createTime",task.getCreateTime());
            String flowNo = task.getProcessDefinitionId().split(":")[0];
            if(flowNo.equals("studentLeaveSelfApply")){
                LambdaQueryWrapper<StudentLeaveSelfApplyVO> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(StudentLeaveSelfApplyVO::getProcessId,task.getProcessInstanceId());
                StudentLeaveSelfApplyVO studentLeaveSelfApplyVO = studentLeaveSelfApplyDao.selectOne(wrapper);
                if(studentLeaveSelfApplyVO == null){
                    continue;
                }
                flowVO.setApplicant(studentLeaveSelfApplyVO.getStudentName());
            }
            if(flowNo.equals("studentLeaveWithdrawal")){
                LambdaQueryWrapper<StudentLeaveApplyVO> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(StudentLeaveApplyVO::getProcessId,task.getProcessInstanceId());
                StudentLeaveApplyVO studentLeaveApplyVO = studentLeaveApplyDao.selectOne(wrapper);
                flowVO.setApplicant(studentLeaveApplyVO.getStudentName());
            }
            leaveTasks.add(flowVO);
        }
        IPage ipage = new Page();
        ipage.setTotal(count);
        ipage.setRecords(leaveTasks);
        return ipage;
    }

    @Override
    public List<String> findAssigneeList(List<Long> deptIds) {
        SysUser user = SysUserUtils.getSysUser();
        List<String> leaderList = new ArrayList<>();

        for(Long id : deptIds){
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUser::getDeptId,id);
            wrapper.eq(SysUser::getIsDeptLeader,"1");
            List<SysUser> sysUserList = sysUserDao.selectList(wrapper);
            if(sysUserList!=null && sysUserList.size()>0){
                leaderList.add(sysUserList.get(0).getUsername());
            }

        }
        return leaderList;
    }

    @Override
    public IPage<WorkFlowVO> findHistoryApproval(WorkFlowVO vo) {
        String username = SysUserUtils.getSysUser().getUsername();
        int startNum=(vo.getPageNum()-1)*vo.getPageSize();
        List<HistoricTaskInstance> hisTaskList = historyService.createHistoricTaskInstanceQuery().finished()
                .taskInvolvedUser(username)
                .processDefinitionKey(vo.getApplyID())
                .orderByTaskCreateTime().desc().listPage(startNum,vo.getPageSize());
        Long count = historyService.createHistoricTaskInstanceQuery().finished().taskInvolvedUser(username)
                .processDefinitionKey(vo.getApplyID()).count();
        List<WorkFlowVO> leaveTasks = new ArrayList<>();
        for (HistoricTaskInstance task : hisTaskList) {
//            List<HistoricTaskInstance> hTask = historyService.createHistoricTaskInstanceQuery()
//                    .processDefinitionKey(task.getProcessDefinitionKey()).taskAssignee(username).list();
            WorkFlowVO flowVO = new WorkFlowVO();
            flowVO.setTaskId(task.getId());
            flowVO.setName(task.getName());
            flowVO.setProcessInstanceId(task.getProcessInstanceId());
            flowVO.setProcessDefinitionId(task.getProcessDefinitionId());
            flowVO.setCreateTime(task.getStartTime());
            String flowNo = task.getProcessDefinitionId().split(":")[0];
            if(flowNo.equals("studentLeaveSelfApply")){
                LambdaQueryWrapper<StudentLeaveSelfApplyVO> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(StudentLeaveSelfApplyVO::getProcessId,task.getProcessInstanceId());
                StudentLeaveSelfApplyVO studentLeaveSelfApplyVO = studentLeaveSelfApplyDao.selectOne(wrapper);
                if(studentLeaveSelfApplyVO!=null){
                    flowVO.setApplicant(studentLeaveSelfApplyVO.getStudentName());
                    flowVO.setEntityObject(studentLeaveSelfApplyVO);
                }
            }
            if(flowNo.equals("studentLeaveWithdrawal")){
                LambdaQueryWrapper<StudentLeaveApplyVO> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(StudentLeaveApplyVO::getProcessId,task.getProcessInstanceId());
                StudentLeaveApplyVO studentLeaveApplyVO = studentLeaveApplyDao.selectOne(wrapper);
                flowVO.setApplicant(studentLeaveApplyVO.getStudentName());
            }
            leaveTasks.add(flowVO);
        }
        IPage ipage = new Page();
        ipage.setTotal(count);
        ipage.setRecords(leaveTasks);
        return ipage;
    }

    //多租户
    @Override
    public List<ActReProcdef> findAllDeployFlow() {
        List<ActReProcdef> allLastDeployFlow = workFlowCommonDao.getLastDeployFlow();
        List<ActReProcdef> returnList = new ArrayList<>();
        for(ActReProcdef item :  allLastDeployFlow){
            ActReProcdef actReProcdef = workFlowCommonDao.getFlowByKeyAndVersion(item.getKey(),item.getVersion());
            returnList.add(actReProcdef);
        }
        return returnList;
    }

    @Autowired
    private TenantFlowDao tenantFlowDao;

    @Override
    public int tieUpTenant(TenantFlow tenantFlow) {

        String tenantId = SysUserUtils.getSysUser().getTenantId();
        ActReProcdef flowByTypeAndTenant = workFlowCommonDao.findFlowByTypeAndTenant(tenantFlow.getType(), tenantId);
        if(flowByTypeAndTenant != null){
            return -1;
        }
        tenantFlow.setTenantId(tenantId);
        tenantFlow.setCreateTime(new Date());
        return tenantFlowDao.insert(tenantFlow);

    }

    @Override
    public ActReProcdef findFlowByTypeAndTenant(TenantFlow tenantFlow) {
        String tenantId = SysUserUtils.getSysUser().getTenantId();

        return workFlowCommonDao.findFlowByTypeAndTenant(tenantFlow.getType(),tenantId);
    }

    @Override
    public int deleteTaskList(List<String> taskIdList) {
        try{
            for(String taskId : taskIdList){
                runtimeService.deleteProcessInstance(taskId,"deleted to remove running task");
            }
        }catch (Exception e){
            log.info(e.getMessage());
            return -1;
        }
        return 1;
    }

    //多租户

    //    @Override
//    public InputStream getFlowImgByProcInstId(String procDefId, String procInstId, boolean showHistory) throws Exception {
//        InputStream imageStream = null;
//        BpmnModel bpmnModel = null;
//
//        List<String> highLightedActivitiIdList = new ArrayList<>();
//        List<String> runningActivitiIdList = new ArrayList<>();
//        List<String> highLightedFlowIds = new ArrayList<>();
//
//        if (showHistory && !StringUtils.isEmpty(procInstId)) {
//            // 通过流程实例ID获取历史流程实例
//            HistoricProcessInstance historicProcessInstance = historyService
//                    .createHistoricProcessInstanceQuery()
//                    .processInstanceId(procInstId)
//                    .singleResult();
//
//            if (null != historicProcessInstance) {
//
//                // 获取流程定义Model对象
//                bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
//
//                //如果需要展示历史节点记录，则需要查询出对应的历史节点信息
//                if (showHistory) {
//                    // 通过流程实例ID获取流程中已经执行的节点，按照执行先后顺序排序
//                    List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
//                            .processInstanceId(procInstId)
//                            .orderByHistoricActivityInstanceId()
//                            .asc().list();
//
//                    // 将已经执行的节点ID放入高亮显示节点集合
//                    for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
//                        highLightedActivitiIdList.add(historicActivityInstance.getActivityId());
//                    }
//
//                    // 通过流程实例ID获取流程中正在执行的节点
//                    List<Execution> runningActivityInstanceList = runtimeService.createExecutionQuery().
//                            processInstanceId(procInstId).list();
//                    for (Execution execution : runningActivityInstanceList) {
//                        if (!StringUtils.isEmpty(execution.getActivityId())) {
//                            runningActivitiIdList.add(execution.getActivityId());
//                        }
//                    }
//
//                    // 获取已流经的流程线，需要高亮显示高亮流程已发生流转的线id集合
//                    highLightedFlowIds.addAll(getHighLightedFlows(bpmnModel, historicActivityInstanceList));
//                }
//            }
//        } else if (!showHistory && !StringUtils.isEmpty(procDefId)) {
//            bpmnModel = repositoryService.getBpmnModel(procDefId);
//        }
//
//
//        try {
//            if (null != bpmnModel) {
//                // 定义流程画布生成器
//                CustomProcessDiagramGenerator processDiagramGenerator = new CustomProcessDiagramGenerator();
//
//                // 使用默认配置获得流程图表生成器，并生成追踪图片字符流
//                imageStream = processDiagramGenerator.generateDiagramCustom(bpmnModel, "png",
//                        highLightedActivitiIdList, runningActivitiIdList, highLightedFlowIds,
//                        "宋体", "黑体", "黑体",
//                        null, 2.0);
//            }
//
//
//        } catch (Exception e) {
//            log.error("通过流程实例ID[{}]获取流程图时出现异常！", procInstId, e);
//            throw new Exception("通过流程实例ID" + procInstId + "获取流程图时出现异常！", e);
//        }
//
//        return imageStream;
//    }

    /**
     * 获取已流经的流程线，需要高亮显示高亮流程已发生流转的线id集合
     *
     * @param bpmnModel
     * @param historicActivityInstanceList
     * @return
     */
//    private List<String> getHighLightedFlows(BpmnModel bpmnModel,
//                                             List<HistoricActivityInstance> historicActivityInstanceList) {
//        // 已流经的流程线，需要高亮显示
//        List<String> highLightedFlowIdList = new ArrayList<>();
//        // 全部活动节点
//        List<FlowNode> allHistoricActivityNodeList = new ArrayList<>();
//        // 已完成的历史活动节点
//        List<HistoricActivityInstance> finishedActivityInstanceList = new ArrayList<>();
//
//        for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
//            // 获取流程节点
//            FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance
//                    .getActivityId(), true);
//            allHistoricActivityNodeList.add(flowNode);
//            // 结束时间不为空，当前节点则已经完成
//            if (historicActivityInstance.getEndTime() != null) {
//                finishedActivityInstanceList.add(historicActivityInstance);
//            }
//        }
//
//        FlowNode currentFlowNode = null;
//        FlowNode targetFlowNode = null;
//        HistoricActivityInstance currentActivityInstance;
//        // 遍历已完成的活动实例，从每个实例的outgoingFlows中找到已执行的
//        for (int k = 0; k < finishedActivityInstanceList.size(); k++) {
//            currentActivityInstance = finishedActivityInstanceList.get(k);
//            // 获得当前活动对应的节点信息及outgoingFlows信息
//            currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance
//                    .getActivityId(), true);
//            // 当前节点的所有流出线
//            List<SequenceFlow> outgoingFlowList = currentFlowNode.getOutgoingFlows();
//
//            /**
//             * 遍历outgoingFlows并找到已流转的 满足如下条件认为已流转：
//             * 1.当前节点是并行网关或兼容网关，则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转
//             * 2.当前节点是以上两种类型之外的，通过outgoingFlows查找到的时间最早的流转节点视为有效流转
//             * (第2点有问题，有过驳回的，会只绘制驳回的流程线，通过走向下一级的流程线没有高亮显示)
//             */
//            if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(
//                    currentActivityInstance.getActivityType())) {
//                // 遍历历史活动节点，找到匹配流程目标节点的
//                for (SequenceFlow outgoingFlow : outgoingFlowList) {
//                    // 获取当前节点流程线对应的下级节点
//                    targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(outgoingFlow.getTargetRef(),
//                            true);
//                    // 如果下级节点包含在所有历史节点中，则将当前节点的流出线高亮显示
//                    if (allHistoricActivityNodeList.contains(targetFlowNode)) {
//                        highLightedFlowIdList.add(outgoingFlow.getId());
//                    }
//                }
//            } else {
//                /**
//                 * 2、当前节点不是并行网关或兼容网关
//                 * 【已解决-问题】如果当前节点有驳回功能，驳回到申请节点，
//                 * 则因为申请节点在历史节点中，导致当前节点驳回到申请节点的流程线被高亮显示，但实际并没有进行驳回操作
//                 */
//                // 当前节点ID
//                String currentActivityId = currentActivityInstance.getActivityId();
//                int size = historicActivityInstanceList.size();
//                boolean ifStartFind = false;
//                boolean ifFinded = false;
//                HistoricActivityInstance historicActivityInstance;
//                // 循环当前节点的所有流出线
//                // 循环所有历史节点
//                log.info("【开始】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线", currentActivityId);
//                log.info("循环历史节点");
//                for (int i = 0; i < historicActivityInstanceList.size(); i++) {
//                    // // 如果当前节点流程线对应的下级节点在历史节点中，则该条流程线进行高亮显示（【问题】有驳回流程线时，即使没有进行驳回操作，因为申请节点在历史节点中，也会将驳回流程线高亮显示-_-||）
//                    // if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
//                    // Map<String, Object> map = new HashMap<>();
//                    // map.put("highLightedFlowId", sequenceFlow.getId());
//                    // map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
//                    // tempMapList.add(map);
//                    // // highLightedFlowIdList.add(sequenceFlow.getId());
//                    // }
//                    // 历史节点
//                    historicActivityInstance = historicActivityInstanceList.get(i);
//                    log.info("第【{}/{}】个历史节点-ActivityId=[{}]", i + 1, size, historicActivityInstance.getActivityId());
//                    // 如果循环历史节点中的id等于当前节点id，从当前历史节点继续先后查找是否有当前节点流程线等于的节点
//                    // 历史节点的序号需要大于等于已完成历史节点的序号，防止驳回重审一个节点经过两次是只取第一次的流出线高亮显示，第二次的不显示
//                    if (i >= k && historicActivityInstance.getActivityId().equals(currentActivityId)) {
//                        log.info("第[{}]个历史节点和当前节点一致-ActivityId=[{}]", i + 1, historicActivityInstance
//                                .getActivityId());
//                        ifStartFind = true;
//                        // 跳过当前节点继续查找下一个节点
//                        continue;
//                    }
//                    if (ifStartFind) {
//                        log.info("[开始]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);
//
//                        ifFinded = false;
//                        for (SequenceFlow sequenceFlow : outgoingFlowList) {
//                            // 如果当前节点流程线对应的下级节点在其后面的历史节点中，则该条流程线进行高亮显示
//                            // 【问题】
//                            log.info("当前流出线的下级节点=[{}]", sequenceFlow.getTargetRef());
//                            if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
//                                log.info("当前节点[{}]需高亮显示的流出线=[{}]", currentActivityId, sequenceFlow.getId());
//                                highLightedFlowIdList.add(sequenceFlow.getId());
//                                // 暂时默认找到离当前节点最近的下一级节点即退出循环，否则有多条流出线时将全部被高亮显示
//                                ifFinded = true;
//                                break;
//                            }
//                        }
//                        log.info("[完成]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);
//                    }
//                    if (ifFinded) {
//                        // 暂时默认找到离当前节点最近的下一级节点即退出历史节点循环，否则有多条流出线时将全部被高亮显示
//                        break;
//                    }
//                }
//                log.info("【完成】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线", currentActivityId);
//            }
//
//        }
//        return highLightedFlowIdList;
//    }

}
